package net.qiqbframework.tracing;


import net.qiqbframework.messaging.Message;

import java.util.function.Supplier;


public class NoOpSpanFactory implements SpanFactory {

    public static final NoOpSpanFactory INSTANCE = new NoOpSpanFactory();

    @Override
    public Span createRootTrace(Supplier<String> operationNameSupplier) {
        return NoOpSpan.INSTANCE;
    }

    @Override
    public Span createHandlerSpan(Supplier<String> operationNameSupplier, Message<?> parentMessage,
                                  boolean isChildTrace,
                                  Message<?>... linkedParents) {
        return NoOpSpan.INSTANCE;
    }

    @Override
    public Span createDispatchSpan(Supplier<String> operationNameSupplier, Message<?> parentMessage,
                                   Message<?>... linkedSiblings) {
        return NoOpSpan.INSTANCE;
    }

    @Override
    public Span createInternalSpan(Supplier<String> operationNameSupplier) {
        return NoOpSpan.INSTANCE;
    }

    @Override
    public Span createInternalSpan(Supplier<String> operationNameSupplier, Message<?> message) {
        return NoOpSpan.INSTANCE;
    }

    @Override
    public void registerSpanAttributeProvider(SpanAttributesProvider supplier) {
        // Do nothing
    }

    @Override
    public <M extends Message<?>> M propagateContext(M message) {
        return message;
    }

    /**
     * The {@link Span} implementation that does nothing.
     */
    public static class NoOpSpan implements Span {

        /**
         * Instance of a {@link NoOpSpan} that can be used to avoid creating new instances.
         */
        public static final NoOpSpan INSTANCE = new NoOpSpan();

        @Override
        public Span start() {
            return this;
        }

        @Override
        public SpanScope makeCurrent() {
            return () -> {
            };
        }

        @Override
        public void end() {
            // Do nothing
        }

        @Override
        public Span recordException(Throwable t) {
            return this;
        }

        @Override
        public Span addAttribute(String key, String value) {
            return this;
        }
    }
}
